-- sFilter
-- Copyright (c) 2009, Nils Ruesch
-- All rights reserved.
-- Edited by ALZA, Affli and me

local module = {}
module.name = "AuraWatch"
module.Init = function()
	if not SCDB.modules[module.name] then return end
	
	if SCDB[module.name] == nil then SCDB[module.name] = {} end
	
	if SCDB[module.name].Spells == nil then
		SCDB[module.name] = {}
		SCDB[module.name].Spells = {}
		SCDB[module.name].Spells["DRUID"] = {
			{ spellId = 69369, size = 32, unitId = "player", isMine = 1, filter = "HELPFUL", setPoint = {"CENTER"}}, --instants
			{ spellId = 50334, size = 32, unitId = "player", isMine = 1, filter = "HELPFUL", setPoint = {"CENTER"}}, --berserk
			{ spellId = 23920, size = 32, unitId = "target", isMine = 1, filter = "HELPFUL", setPoint = {"CENTER"}}, --spell reflect
			{ spellId = 8177, size = 32, unitId = "target", isMine = 1, filter = "HELPFUL", setPoint = {"CENTER"}}, --grounding totem
		}
		SCDB[module.name].Spells["SHAMAN"] = {
			{ spellId = 23920, size = 32, unitId = "target", isMine = 1, filter = "HELPFUL", setPoint = {"CENTER"}}, --spell reflect
			{ spellId = 8177, size = 32, unitId = "target", isMine = 1, filter = "HELPFUL", setPoint = {"CENTER"}}, --grounding totem
		}
		
		SCDB[module.name].Spells.vtype = "AuraWatch"
	end
	
	local AuraWatch = {}
	local configmode = false
	local class = select(2, UnitClass("player"))

	local MyUnits = {
		 player = true,
		 vehicle = true,
		 pet = true,
	}
	
	local buttons = {}
	
	local function NewEditBox(parent, value)
		local editbox = CreateFrame("EditBox", nil, parent)
		editbox:SetAutoFocus(false)
		editbox:SetMultiLine(false)
		editbox:SetWidth(220); editbox:SetHeight(20)
		editbox:SetMaxLetters(255)
		editbox:SetTextInsets(3,0,0,0)
		editbox:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8x8" })
		editbox:SetBackdropColor(0,0,0,0.5)
		editbox:SetBackdropBorderColor(0,0,0,1)
		editbox:SetFontObject(GameFontHighlight)
		
		editbox:SetScript("OnEscapePressed", function(self) self:ClearFocus() self:SetText(self.value or "") end)
		editbox:SetScript("OnEnterPressed", function(self) self:ClearFocus() self.value = self:GetText() end)

		local label = parent:CreateFontString(nil, "OVERLAY", "GameFontNormal")
		label:SetText(value)
		label:SetWidth(220); label:SetHeight(20)
		label:SetJustifyH("LEFT")
		label:SetPoint("BOTTOMLEFT", editbox, "TOPLEFT", 0, 2)
		
		return editbox
	end
	
	local cframe = CreateFrame("frame", "SpellsConfigFrame", UIParent)
	cframe:SetWidth(240); cframe:SetHeight(200)
	cframe:SetPoint("CENTER")
	cframe:SetBackdrop({ bgFile = "Interface\\ChatFrame\\ChatFrameBackground", edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border", tileSize = 16, edgeSize = 16, insets = {left=3, right=3, top=3, bottom=3}, })
	cframe:SetBackdropColor(.1, .2, .3, 1)
	cframe:SetBackdropBorderColor(.4, .4, .4, 1)

	cframe:EnableMouse(true)
	cframe:SetMovable(true)
	cframe:SetUserPlaced(true)
	cframe:SetClampedToScreen(true)
	cframe:SetScript("OnMouseDown", function(self) self:StartMoving() end)
	cframe:SetScript("OnMouseUp", function(self) self:StopMovingOrSizing() end)
	cframe:SetFrameStrata("DIALOG")

	local closeb = CreateFrame("button", "$parentCloseButton", cframe, "UIPanelCloseButton")
	closeb:SetPoint("TOPRIGHT")
	closeb:SetScript("OnClick", function() cframe:Hide() end)
	
	cframe.title = cframe:CreateFontString("$parentTitle", "OVERLAY", "GameFontNormal")
	cframe.title:SetPoint("TOPLEFT", 0, -10)
	cframe.title:SetWidth(220)
	
	cframe.unitID = NewEditBox(cframe, "Watching unit:")
	cframe.unitID:SetPoint("TOPLEFT", 10, -60)
	cframe.unitID:SetScript("OnEnter", function(self)
		GameTooltip:ClearLines()
		GameTooltip:SetOwner(self, ANCHOR_TOPRIGHT)
		GameTooltip:AddLine("Possible values like 'player', 'pet', 'target', 'focus' and etc.")
		GameTooltip:Show()
	end)
	cframe.unitID:SetScript("OnLeave", function() GameTooltip:Hide() end)
	
	cframe.filter = NewEditBox(cframe, "Spell Filter:")
	cframe.filter:SetPoint("TOPLEFT", 10, -110)
	cframe.filter:SetScript("OnEnter", function(self)
		GameTooltip:ClearLines()
		GameTooltip:SetOwner(self, ANCHOR_TOPRIGHT)
		GameTooltip:AddLine("Values like a 'HARMFUL', 'HELPFUL' and etc.")
		GameTooltip:Show()
	end)
	cframe.filter:SetScript("OnLeave", function() GameTooltip:Hide() end)
	
	
	cframe.isMine = CreateFrame("CheckButton", "$parentIsMine", cframe, "InterfaceOptionsCheckButtonTemplate")
	_G[cframe.isMine:GetName().."Text"]:SetText("Only my spells")
	cframe.isMine:SetScript("OnClick", function(self) if self.value==1 then self.value = 0 else self.value = 1 end end)
	cframe.isMine:SetPoint("TOPLEFT", cframe, 10, -140)
		
	cframe:Hide()
	
	function AuraWatch:ShowConfig(data)
		local spellName, _, spellIcon = GetSpellInfo(data.spellId)
		cframe.title:SetText(format("|T%s:24:24:0:0:64:64:4:60:4:60|t %s, |cffaaffdd[%s]|r", spellIcon, spellName, data.spellId))
		cframe.unitID.value = data.unitId
		cframe.unitID:SetText(data.unitId)
		cframe.filter.value = data.filter
		cframe.filter:SetText(data.filter)
		cframe.isMine.value = data.isMine or
		cframe.isMine:SetChecked((data.isMine or 1))
		cframe:Show()
		cframe:SetScript("OnHide", function(self)
			data.unitId = self.unitID.value
			data.filter = self.filter.value
			data.isMine = self.isMine.value
			for i,v in pairs(buttons) do
				v.selected = false
			end
			AuraWatch:MakeList()
		end)
	end
	
	function AuraWatch:MakeWatch(data)
		local spellName, _, spellIcon = GetSpellInfo(data.spellId)
		local buttonName = "AuraWatch_"..data.spellId
		local button = _G[buttonName] or CreateFrame("Frame", buttonName, UIParent)
		button:SetWidth(data.size)
		button:SetHeight(data.size)
		button:SetPoint(unpack(data.setPoint))
		
		button:RegisterEvent("UNIT_AURA")
		button:RegisterEvent("PLAYER_TARGET_CHANGED")
		button:RegisterEvent("PLAYER_ENTERING_WORLD")
		
		if(not button.found) then
			button:SetAlpha(0)
		end
		
		local function UpdateButton(self, event, ...)
			local unit = ...
			if(data.unitId==unit or event=="PLAYER_TARGET_CHANGED" or event=="PLAYER_ENTERING_WORLD") then
				self.found = false
				self:SetAlpha(1)
				for i=1, 40 do
					local name, rank, icon, count, debuffType, duration, expirationTime, caster, isStealable = UnitAura(data.unitId, i, data.filter)
					if((data.isMine~=1 or MyUnits[caster]) and (name==GetSpellInfo(data.spellId) or (data.spellId2 and name==GetSpellInfo(data.spellId2)) or (data.spellId3 and name==GetSpellInfo(data.spellId3)) or (data.spellId4 and name==GetSpellInfo(data.spellId4)) or (data.spellId5 and name==GetSpellInfo(data.spellId5)))) then
						self.found = true
						self.icon:SetTexture(icon)
						self:SetID(i)
						self.filter = data.filter
			
						self.count:SetText(count>1 and count or "")
						if(duration>0) then
							self.cooldown:Show()
							CooldownFrame_SetTimer(self.cooldown, expirationTime-duration, duration, 1)
						else
							self.cooldown:Hide()
						end
						break
					end
				end

				if(not self.found) then
					self:SetAlpha(0)
					self.icon:SetTexture(spellIcon)
					self.count:SetText("")
					self.cooldown:Hide()
				end
			end

			if(configmode==true) then
				self:SetAlpha(1)
				self.count:SetText(3)
			end
		end
		
		if button:GetScript("OnEvent") == nil then
			button:SetScript("OnEvent", UpdateButton)
		end
		
		button.icon = _G[buttonName.."Icon"] or button:CreateTexture(buttonName.."Icon", "BACKGROUND")
		button.icon:SetPoint("TOPLEFT", 4, -4)
		button.icon:SetPoint("BOTTOMRIGHT", -4, 4)
		button.icon:SetTexture(spellIcon)
		button.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93)

		button.count = _G[buttonName.."Count"] or button:CreateFontString(buttonName.."Count", "OVERLAY", "GameFontHighlight")
		button.count:SetFont(button.count:GetFont(), ceil(button:GetWidth()/3.2), "OUTLINE")
		button.count:SetPoint("TOPLEFT", 4, -4)
		button.count:SetJustifyH("CENTER")

		button.cooldown = _G[buttonName.."Cooldown"] or CreateFrame("Cooldown", buttonName.."Cooldown", button, "CooldownFrameTemplate")
		button.cooldown:SetAllPoints(button.icon)
		button.cooldown:SetReverse()
		
		button.overlay = _G[buttonName.."Overlay"] or button:CreateTexture(buttonName.."Overlay", "OVERLAY")
		button.overlay:SetTexture("Interface\\Buttons\\UI-TotemBar")
		button.overlay:SetTexCoord(1 / 128, 35 / 128, 207 / 256, 240 / 256)
		button.overlay:SetDesaturated(1)
		button.overlay:SetVertexColor(.6,.6,.6)
		button.overlay:SetAllPoints(button)
		
		button:SetResizable(true)
		button:SetMovable(true)
		button:SetResizable(true)
		button:EnableMouse(false)
		button:SetClampedToScreen(true)
		button:RegisterForDrag("LeftButton")
		  
		button.resize = _G[buttonName.."ResizeButton"] or CreateFrame("button", buttonName.."ResizeButton", button)
		button:SetMinResize(16, 16)
		button:SetMaxResize(160, 160)
		button.resize:SetPoint("BOTTOMRIGHT")
		button.resize:SetWidth(16)
		button.resize:SetHeight(16)
		button.resize:SetNormalTexture("Interface\\CHATFRAME\\UI-ChatIM-SizeGrabber-Highlight")
		button.resize:SetHighlightTexture("Interface\\CHATFRAME\\UI-ChatIM-SizeGrabber-Highlight")
		button.resize:SetPushedTexture("Interface\\CHATFRAME\\UI-ChatIM-SizeGrabber-Down")
      
		button.resize:SetScript("OnMouseDown", function(self, buttonkey) 
			if buttonkey == "LeftButton" then button:StartSizing() end
		end)
		
		button.resize:SetScript("OnMouseUp", function(self, buttonkey)
			if buttonkey == "LeftButton" then
				button:StopMovingOrSizing()
				button:SetHeight(math.max(button:GetWidth(), button:GetHeight()))
				data.size = math.max(button:GetWidth(), button:GetHeight()) or 30
			end
		end)
		
		if button.selected == true then
			button.overlay:SetVertexColor(1,0,0)
		else
			button.overlay:SetVertexColor(.6,.6,.6)
		end
				
		if (configmode == true) then
			button:SetScript("OnEnter", function(self)
				GameTooltip:SetOwner(self, "ANCHOR_BOTTOMLEFT")
				GameTooltip:ClearLines()
				GameTooltip:SetFrameLevel(self:GetFrameLevel() + 2)
				GameTooltip:SetUnitAura(PlayerFrame.unit, self:GetID(), self.filter or "")
				GameTooltip:AddLine("|cffff8888RightClick for more options|r")
				GameTooltip:Show()
			end)
			button:SetScript("OnLeave", function() GameTooltip:Hide() end)
	
			button.resize:Show()
			button.count:Hide()
			button.icon:SetDesaturated(1)
			button:EnableMouse(true)
			button:RegisterForDrag("LeftButton")
			button:SetScript("OnMouseDown", function(self, buttonkey) 
				if buttonkey == "LeftButton" then
					self:StartMoving() 
				elseif buttonkey == "RightButton" then
					for i,v in pairs(buttons) do
						v.selected = false
					end
					button.selected = true
					AuraWatch:MakeList()
					AuraWatch:ShowConfig(data)
				end
			end)
			button:SetScript("OnMouseUp", function(self, buttonkey)
				if buttonkey == "LeftButton" then
					self:StopMovingOrSizing()
					local x, y = self:GetCenter()
					data.setPoint = {"BOTTOMLEFT", x-data.size/2, y-data.size/2}
				end
			end)
		else
			button:RegisterForDrag(nil)
			button:SetScript("OnEnter", nil)
			button:SetScript("OnLeave", nil)
			
			button.resize:Hide()
			button.count:Show()
			button.icon:SetDesaturated(0)
			button:EnableMouse(false)
			button:SetScript("OnMouseDown", nil)
			button:SetScript("OnMouseUp", nil)
		end
		
		UpdateButton(button, "PLAYER_TARGET_CHANGED")
		return button
	end
	
	function AuraWatch:MakeList()
		table.wipe(buttons)
		buttons = {}
		if SCDB[module.name].Spells[class] == nil then SCDB[module.name].Spells[class] = {} end
		if(SCDB[module.name].Spells and SCDB[module.name].Spells[class]) then
			for index, value in pairs(SCDB[module.name].Spells[class]) do
				tinsert(buttons, AuraWatch:MakeWatch(value))
			end
		end
	end
	
	WorldFrame:HookScript("OnMouseUp", function(self, buttonkey)
		if buttonkey == "LeftButton" then
			for i,v in pairs(buttons) do
				v.selected = false
			end
			AuraWatch:MakeList()
			cframe:Hide()
		end
	end)
	
	AuraWatch:MakeList()
	print("|cff00aaddAuraWatch|r loaded. Type |cffff8888/aw help|r for more options")

	-- setup slash command
	SLASH_AuraWatch1 = "/aw";
	SlashCmdList["AuraWatch"] = function(cmd)
		local command, spellID = cmd:match("^(%S*)%s*(.-)$")
		
		if (command == "" and spellID == "") and #SCDB[module.name].Spells[class]>0 then
			configmode = not configmode
			if not configmode then cframe:Hide() end
		elseif (command == "help" and spellID == "") or (command == "" and #SCDB[module.name].Spells[class]==0) then
			print("|cff00aaddAuraWatch|r Options: /aw <option>")
			print("/aw : lock/unlock all spell icons")
			print("/aw help : this help")
			print("/aw add <spell ID> : adding a spell to watch")
			print("/aw del <spell ID> : delete watching spell")
			print("/aw list : show list of all spells")
			print("after adding or deleting spells you should to reload UI for save settings")
		elseif command == "list" and spellID == "" then
			if SCDB[module.name].Spells and SCDB[module.name].Spells[class] then
				print("|cff00aaddAuraWatch|r - Existing spells:")
				for index=1, #SCDB[module.name].Spells[class] do
					local sID = SCDB[module.name].Spells[class][index].spellId
					local spellName, _, spellIcon = GetSpellInfo(sID)
					print(format("|T%s:16:16:0:0:64:64:4:60:4:60|t %s, |cffaaffdd[%s]|r", spellIcon or "", spellName or "", sID))
				end
			end
		elseif command == "add" and spellID ~= "" then
			local spellName, _ = GetSpellInfo(spellID)
			table.insert(SCDB[module.name].Spells[class], {["spellId"] = spellID, ["size"] = 32, ["unitId"] = "player", ["isMine"] = 1, ["filter"] = "HELPFUL", ["setPoint"] = {"CENTER"}})
			print("after adding or deleting spells you should to reload UI for save settings")
		elseif command == "del" and spellID ~= "" then
			if SCDB[module.name].Spells and SCDB[module.name].Spells[class] then
				for index=1, #SCDB[module.name].Spells[class] do
					if SCDB[module.name].Spells[class][index].spellId == spellID then
						tremove(SCDB[module.name].Spells[class], index)
						print("after adding or deleting spells you should to reload UI for save settings")
					end
				end
			end
		end
		AuraWatch:MakeList()
	end
end
tinsert(SuperClassic.modules, module) -- finish him!